﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>



//int main()
//{
//	int a = 6;
//	int b =(a << 1);//移位规则：左边抛弃、右边补0
//	printf("%d\n", a);
//	printf("%d\n", b);
//	return 0;
//}


//右移到底是算术右移还是逻辑右移是取决于编译器的实现，常见的编译器都是算术右移
//1.逻辑右移：左边⽤0填充，右边丢弃
//2.算术右移：左边⽤原该值的符号位填充，右边丢弃
//int main()
//{
//	int a = 6;
//	int b = (a >> 1);//移位规则：左边抛弃、右边补0
//	printf("%d\n", a);
//	printf("%d\n", b);
//	return 0;
//}

// ^ 按位异或：相同为0.互异为1
// ~ 按位取反：全部取反
//int main()
//{
//	int a = 0;
//	int b = ~a;
//	printf("%d\n", b);
//	return 0;
//}


//不能创建临时变量（第三个变量），实现两个数的交换
//int main()
//{
//	int a = 3;
//	int b = 5;
//	printf("交换前：a=%d b=%d\n", a, b);//0^a=a   a^a=0
//	a = a ^ b;
//	b = a ^ b;
//	a = a ^ b;
//	printf("交换后：a=%d b=%d\n", a, b);
//	return 0;
//}


//编写代码实现：求⼀个整数存储在内存中的⼆进制中1的个数。

//int main()
//{
//	unsigned int n = 0;
//	scanf("%d", &n);
//	int count = 0;
//	while (n)
//	{
//		if (n % 2 == 1)
//		{
//			count++;
//			n /= 2;
//		}
//	}
//	printf("%d\n", count);
//	return 0;
//}

//int main()
//{
//    int n = 0;
//	scanf("%d", &n);
//	int count = 0;
//	int i = 0;
//	for (i = 0; i <32; i++)
//	{
//		if ((n >> i) & 1 == 1)
//			count++;
//	}
//	printf("%d\n", count);
//	return 0;
//}


//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int count = 0;
//	while (n)
//	{
//		n = n & (n - 1);
//		count++;
//	}
//	printf("%d\n", count);
//	return 0;
//}


//如何判断一个数是2的次方数

//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	if (n & (n - 1) == 0)
//	{
//		printf("是2的次方数");
//	}
//	else
//	{
//		printf("不是2的次方数");
//	}
//	return 0;
//}

//编写代码将13⼆进制序列的第5位修改为1，然后再改回0
//int main()
//{
//	int n = 13;
//	n = n | (1 << 4);
//	printf("%d\n", n);
//	n = n & (~(1 << 4));
//	printf("%d\n", n);
//	return 0;
//}


//int main()
//{
//	int a = 1;
//	int b = 2;
//	int c = (a > b, a = b + 10, a, b = a + 1);
//	printf("%d\n", c);
//	return 0;
//}


//int main()
//{
//	int a = 0;
//	int b = 0;
//	int c = 0;
//	int d = 0;
//	if (a = b + 1, c = a / 2, d > 0);
//	printf("%d\n", c);
//	return 0;
//}


//struct Point
//{
//	int x;
//	int y;
//}p1; //声明类型的同时定义变量p1 
//struct Point p2; //定义结构体变量p2 
////代码2:初始化。 
//struct Point p3 = { 10, 20 };
//struct Stu //类型声明
//{
//	char name[15];//名字 
//	int age; //年龄 
//};
//struct Stu s1 = { "zhangsan", 20 };//初始化 
//struct Stu s2 = { .age = 20, .name = "lisi" };//指定顺序初始化 
////代码3 
//struct Node
//{
//	int data;
//	struct Point p;
//	struct Node* next;
//}n1 = { 10, {4,5}, NULL }; //结构体嵌套初始化 
//struct Node n2 = { 20, {5, 6}, NULL };


//struct Point
//{
//	int x;
//	int y;
//}p = { 1,2 };
//int main()
//{
//	printf("x: %d y: %d\n", p.x,p.y);
//	return 0;
//}


//int main()
//{
//	char a = 3;
//	char b = 127;
//	char c = a + b;
//	printf("%d\n", c);//整形提升  为了获得这个精度，表达式中的字符和短整型操作数在使⽤之前被转换为普通整型，
//	return 0;
//}


//int fun()
//{
//	static int count = 1;
//	return ++count;
//}
//int main()
//{
//	int answer;
//	answer = fun() - fun() * fun();
//	printf("%d\n", answer);//输出多少？ 
//	return 0;
//}


//int main()
//{
//	int i = 1;
//	int ret = (++i) + (++i) + (++i);
//	printf("%d\n", ret);//12
//	printf("%d\n", i);//4
//	return 0;
//}


//内存单元的编号 == 地址 == 指针
//&a取出的是a所占4个字节中地址较⼩的字节的地址
//指针变量也是⼀种变量，这种变量就是⽤来存放地址的，存放在指针变量中的值都会理解为地址
// 
//int main()
//{
//	int a = 10;
//	printf("%p\n", &a);
//	int* p = &a;
//	return 0;
//}

//int main()
//{
//	int a = 100;
//	int* pa = &a;
//	*pa = 0;//* 解引用操作符（间接访问操作符）   
//	printf("%d\n", a);
//	return 0;
//}


//• 32位平台下地址是32个bit位，指针变量⼤⼩是4个字节
//• 64位平台下地址是64个bit位，指针变量⼤⼩是8个字节
//• 注意指针变量的⼤⼩和类型是⽆关的，只要指针类型的变量，在相同的平台下，⼤⼩都是相同的
//指针的类型决定了，对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)
//指针的类型决定了指针向前或者向后⾛⼀步有多⼤（距离）




















































































